local sk__qianyuan = fk.CreateSkill {

  name = "sk__qianyuan",

  tags = {},

}


---潜渊
---@param player ServerPlayer
---@param index integer
---@param count integer
---@param skill_name string
local function DoQianyuan(player, index, count, skill_name)
  local room = player.room
  if index == 1 then
    room:damage {
      to = player,
      damage = count,
      skillName = skill_name,
    }
  elseif index == 2 then
    room:loseHp(player, count, skill_name)
  elseif index == 3 then
    room:changeMaxHp(player, -count)
  elseif index == 4 then
    room:askForDiscard(player, count, count, true, skill_name, false)
  elseif index == 5 then
    local skills = table.map(table.filter(player.player_skills, function(s)
      return s:isPlayerSkill(player) and s.visible
    end), function(s)
      return s.name
    end)
    if #skills > 0 then
      room:handleAddLoseSkills(player, "-" .. table.random(skills), nil, true, false)
    end
  elseif index == 6 then
    for index, value in ipairs(player:getSkillNameList()) do
      room:invalidateSkill(player, value, "-turn")
    end
  elseif index == 7 then
    player:setChainState(true)
  elseif index == 8 then
    player:turnOver()
  end
end

Fk:addQmlMark {
  name = "sk__qianyuan",
  how_to_show = function(name, value)
    if type(value) == "table" then
      return tostring(#value)
    end
    return " "
  end,
  qml_path = "packages/water_jilve/qml/ZhidiBox"
}

local QianyuanMapper = {
  [fk.DamageInflicted] = 1,
  [fk.PreHpLost] = 2,
  [fk.BeforeMaxHpChanged] = 3,
  [fk.BeforeCardsMove] = 4,
  [fk.EventLoseSkill] = 5,
  [fk.AfterSkillEffect] = 6,
  [fk.BeforeChainStateChange] = 7,
  [fk.BeforeTurnOver] = 8,
}

sk__qianyuan:addEffect(fk.DamageInflicted, {
  name = "sk__qianyuan",
  anim_type = "defensive",
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(sk__qianyuan.name) and target == player then
      return target == player and
          (not table.contains(player:getTableMark("@[sk__qianyuan]"), "sk__qianyuan1") or
            player:getMark("sk__qianyuan-turn") < #player.room.alive_players)
    end
  end,
  on_cost = function(self, event, target, player, data)
    if table.contains(player:getTableMark("@[sk__qianyuan]"), "sk__qianyuan1") then
      return player.room:askForSkillInvoke(player, sk__qianyuan.name, nil,
        "#sk__qianyuan2-invoke:::" .. "sk__qianyuan1" .. ":" ..
        player:getMark("sk__qianyuan-turn"))
    else
      return player.room:askForSkillInvoke(player, sk__qianyuan.name, nil,
        "#sk__qianyuan1-invoke:::" .. "sk__qianyuan1")
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if table.contains(player:getTableMark("@[sk__qianyuan]"), "sk__qianyuan1") then
      room:addPlayerMark(player, "sk__qianyuan-turn", 1)

      local nums = { 1, 2, 3, 4, 5, 6, 7, 8 }
      table.removeOne(nums, 1)
      local rand = table.random(nums)
      if rand == 4 and player:isNude() then
        table.removeOne(nums, 4)
        rand = table.random(nums)
      end
      room:sendLog {
        type = "#sk__qianyuanLog",
        from = player.id,
        arg = "sk__qianyuan1",
        arg2 = "sk__qianyuan" .. rand,
        toast = true,
      }
      local count = 1
      if rand < 5 then
        count = player:getMark("sk__qianyuan_record" .. rand) == 0 and 1 or player:getMark("sk__qianyuan_record" .. rand)
      end
      DoQianyuan(player, rand, count, sk__qianyuan.name)
      data:preventDamage()
    else
      room:addTableMark(player, "@[sk__qianyuan]", "sk__qianyuan1")
      room:addPlayerMark(player, "sk__qianyuan_record1", data.damage)
      data:preventDamage()
    end
  end,
})
sk__qianyuan:addEffect(fk.PreHpLost, {
  anim_type = "defensive",
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(sk__qianyuan.name,true) then
      if player:hasSkill(sk__qianyuan.name) then
        if target == player then
          return target == player and
              (not table.contains(player:getTableMark("@[sk__qianyuan]"), "sk__qianyuan2") or
                player:getMark("sk__qianyuan-turn") < #player.room.alive_players)
        end
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    if table.contains(player:getTableMark("@[sk__qianyuan]"), "sk__qianyuan2") then
      return player.room:askForSkillInvoke(player, sk__qianyuan.name, nil,
        "#sk__qianyuan2-invoke:::" .. "sk__qianyuan2" .. ":" ..
        player:getMark("sk__qianyuan-turn"))
    else
      return player.room:askForSkillInvoke(player, sk__qianyuan.name, nil,
        "#sk__qianyuan1-invoke:::" .. "sk__qianyuan2")
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if table.contains(player:getTableMark("@[sk__qianyuan]"), "sk__qianyuan2") then
      room:addPlayerMark(player, "sk__qianyuan-turn", 1)
      local nums = { 1, 2, 3, 4, 5, 6, 7, 8 }
      table.removeOne(nums, 2)
      local rand = table.random(nums)
      if rand == 4 and player:isNude() then
        table.removeOne(nums, 4)
        rand = table.random(nums)
      end
      room:sendLog {
        type = "#sk__qianyuanLog",
        from = player.id,
        arg = "sk__qianyuan2",
        arg2 = "sk__qianyuan" .. rand,
        toast = true,
      }
      local count = 1
      if rand < 5 then
        count = player:getMark("sk__qianyuan_record" .. rand) == 0 and 1 or player:getMark("sk__qianyuan_record" .. rand)
      end
      DoQianyuan(player, rand, count, sk__qianyuan.name)
      data:preventHpLost()
    else
      room:addTableMark(player, "@[sk__qianyuan]", "sk__qianyuan2")
      room:addPlayerMark(player, "sk__qianyuan_record2", data.num)
      data:preventHpLost()
    end
  end,
})
sk__qianyuan:addEffect(fk.BeforeMaxHpChanged, {
  name = "sk__qianyuan",
  anim_type = "defensive",
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(sk__qianyuan.name,true) then
      if player:hasSkill(sk__qianyuan.name) then
        if target == player then
          if data.num > 0 then return end
          return target == player and
              (not table.contains(player:getTableMark("@[sk__qianyuan]"), "sk__qianyuan3") or
                player:getMark("sk__qianyuan-turn") < #player.room.alive_players)
        end
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    if table.contains(player:getTableMark("@[sk__qianyuan]"), "sk__qianyuan3") then
      return player.room:askForSkillInvoke(player, sk__qianyuan.name, nil,
        "#sk__qianyuan2-invoke:::" .. "sk__qianyuan3" .. ":" ..
        player:getMark("sk__qianyuan-turn"))
    else
      return player.room:askForSkillInvoke(player, sk__qianyuan.name, nil,
        "#sk__qianyuan1-invoke:::" .. "sk__qianyuan3")
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if table.contains(player:getTableMark("@[sk__qianyuan]"), "sk__qianyuan3") then
      room:addPlayerMark(player, "sk__qianyuan-turn", 1)
      local nums = { 1, 2, 3, 4, 5, 6, 7, 8 }
      table.removeOne(nums, 3)
      local rand = table.random(nums)
      if rand == 4 and player:isNude() then
        table.removeOne(nums, 4)
        rand = table.random(nums)
      end
      room:sendLog {
        type = "#sk__qianyuanLog",
        from = player.id,
        arg = "sk__qianyuan3",
        arg2 = "sk__qianyuan" .. rand,
        toast = true,
      }
      local count = 1
      if rand < 5 then
        count = player:getMark("sk__qianyuan_record" .. rand) == 0 and 1 or player:getMark("sk__qianyuan_record" .. rand)
      end
      DoQianyuan(player, rand, count, sk__qianyuan.name)
      data:preventMaxHpChange()
    else
      room:addTableMark(player, "@[sk__qianyuan]", "sk__qianyuan3")
      room:addPlayerMark(player, "sk__qianyuan_record3", -data.num)
      data:preventMaxHpChange()
    end
  end,
})
sk__qianyuan:addEffect(fk.BeforeCardsMove, {
  name = "sk__qianyuan",
  anim_type = "defensive",
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(sk__qianyuan.name,true) then
      if player:hasSkill(sk__qianyuan.name) then
        for _, move in ipairs(data) do
          if move.from == player and move.moveReason == fk.ReasonDiscard then
            if (not table.contains(player:getTableMark("@[sk__qianyuan]"), "sk__qianyuan4") or
                  player:getMark("sk__qianyuan-turn") < #player.room.alive_players) then
              for _, info in ipairs(move.moveInfo) do
                if info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip then
                  return true
                end
              end
            end
          end
        end
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    if #player:getTableMark("@[sk__qianyuan]") > 0 and
        table.contains(player:getTableMark("@[sk__qianyuan]"), "sk__qianyuan4") then
      return player.room:askForSkillInvoke(player, sk__qianyuan.name, nil,
        "#sk__qianyuan2-invoke:::" .. "sk__qianyuan4" .. ":" ..
        player:getMark("sk__qianyuan-turn"))
    else
      return player.room:askForSkillInvoke(player, sk__qianyuan.name, nil,
        "#sk__qianyuan1-invoke:::" .. "sk__qianyuan4")
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if table.contains(player:getTableMark("@[sk__qianyuan]"), "sk__qianyuan4") then
      room:addPlayerMark(player, "sk__qianyuan-turn", 1)
      local ids = {}
      for _, move in ipairs(data) do
        if move.from == player and move.moveReason == fk.ReasonDiscard then
          local new_info = {}
          for _, info in ipairs(move.moveInfo) do
            if info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip then
              table.insertIfNeed(ids, info.cardId)
            else
              table.insert(new_info, info)
            end
            if #ids > 0 then
              move.moveInfo = new_info
            end
          end
        end
      end
      room:sendLog {
        type = "#cancelDismantle",
        card = ids,
        arg = sk__qianyuan.name,
      }
      local nums = { 1, 2, 3, 4, 5, 6, 7, 8 }
      table.removeOne(nums, 4)
      local rand = table.random(nums)
      if rand == 4 and player:isNude() then
        table.removeOne(nums, 4)
        rand = table.random(nums)
      end
      room:sendLog {
        type = "#sk__qianyuanLog",
        from = player.id,
        arg = "sk__qianyuan4",
        arg2 = "sk__qianyuan" .. rand,
        toast = true,
      }
      local count = 1
      if rand < 5 then
        count = player:getMark("sk__qianyuan_record" .. rand) == 0 and 1 or player:getMark("sk__qianyuan_record" .. rand)
      end
      DoQianyuan(player, rand, count, sk__qianyuan.name)
    else
      room:addTableMark(player, "@[sk__qianyuan]", "sk__qianyuan4")
      if event == fk.BeforeCardsMove then
        local ids = {}
        for _, move in ipairs(data) do
          if move.from == player and move.moveReason == fk.ReasonDiscard then
            local new_info = {}
            for _, info in ipairs(move.moveInfo) do
              if info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip then
                table.insertIfNeed(ids, info.cardId)
              else
                table.insert(new_info, info)
              end
              if #ids > 0 then
                move.moveInfo = new_info
              end
            end
          end
        end
        room:addPlayerMark(player, "sk__qianyuan_record4", #ids)
        room:sendLog {
          type = "#cancelDismantle",
          card = ids,
          arg = sk__qianyuan.name,
        }
      end
    end
  end,
})
sk__qianyuan:addEffect(fk.EventLoseSkill, {
  name = "sk__qianyuan",
  anim_type = "defensive",
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(sk__qianyuan.name,true) then
      if player:hasSkill(sk__qianyuan.name) then
        if target == player then
          if not (data.skill:isPlayerSkill(player) and data.skill.visible) then return end
          return target == player and
              (not table.contains(player:getTableMark("@[sk__qianyuan]"), "sk__qianyuan5") or
                player:getMark("sk__qianyuan-turn") < #player.room.alive_players)
        end
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    if table.contains(player:getTableMark("@[sk__qianyuan]"), "sk__qianyuan5") then
      return player.room:askForSkillInvoke(player, sk__qianyuan.name, nil,
        "#sk__qianyuan2-invoke:::" .. "sk__qianyuan5" .. ":" ..
        player:getMark("sk__qianyuan-turn"))
    else
      return player.room:askForSkillInvoke(player, sk__qianyuan.name, nil,
        "#sk__qianyuan1-invoke:::" .. "sk__qianyuan5")
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if table.contains(player:getTableMark("@[sk__qianyuan]"), "sk__qianyuan5") then
      room:addPlayerMark(player, "sk__qianyuan-turn", 1)
      room:handleAddLoseSkills(player, data.skill.name, nil, false, false)
      local nums = { 1, 2, 3, 4, 5, 6, 7, 8 }
      table.removeOne(nums, 5)
      local rand = table.random(nums)
      if rand == 4 and player:isNude() then
        table.removeOne(nums, 4)
        rand = table.random(nums)
      end
      room:sendLog {
        type = "#sk__qianyuanLog",
        from = player.id,
        arg = "sk__qianyuan5",
        arg2 = "sk__qianyuan" .. rand,
        toast = true,
      }
      local count = 1
      if rand < 5 then
        count = player:getMark("sk__qianyuan_record" .. rand) == 0 and 1 or player:getMark("sk__qianyuan_record" .. rand)
      end
      DoQianyuan(player, rand, count, sk__qianyuan.name)
    else
      room:addTableMark(player, "@[sk__qianyuan]", "sk__qianyuan5")
      room:handleAddLoseSkills(player, data.skill.name, nil, false, false)
    end
  end,
})
sk__qianyuan:addEffect(fk.AfterSkillEffect, {
  name = "sk__qianyuan",
  anim_type = "defensive",
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(sk__qianyuan.name,true) and table.find(player:getMarkNames(), function(name)
          return name:startsWith(MarkEnum.UncompulsoryInvalidity) or name:startsWith(MarkEnum.InvalidSkills)
        end) then
      return (not table.contains(player:getTableMark("@[sk__qianyuan]"), "sk__qianyuan6") and player:getMark("sk__qianyuan6_n-turn") == 0) or
          (table.contains(player:getTableMark("@[sk__qianyuan]"), "sk__qianyuan6") and
            (player:getMark("sk__qianyuan-turn") < #player.room.alive_players) and player:getMark("sk__qianyuan6_y-turn") == 0)
    end
  end,
  on_cost = function(self, event, target, player, data)
    if table.contains(player:getTableMark("@[sk__qianyuan]"), "sk__qianyuan6") then
      if player.room:askForSkillInvoke(player, sk__qianyuan.name, nil,
            "#sk__qianyuan2-invoke:::" .. "sk__qianyuan6" .. ":" ..
            player:getMark("sk__qianyuan-turn")) == false then
        player.room:addPlayerMark(player, "sk__qianyuan6_y-turn")
        return false
      end
      return true
    else
      if player.room:askForSkillInvoke(player, sk__qianyuan.name, nil,
            "#sk__qianyuan1-invoke:::" .. "sk__qianyuan6") == false then
        player.room:addPlayerMark(player, "sk__qianyuan6_n-turn")
        return false
      end
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if table.contains(player:getTableMark("@[sk__qianyuan]"), "sk__qianyuan6") then
      room:addPlayerMark(player, "sk__qianyuan-turn", 1)
      for _, name in ipairs(player:getMarkNames()) do
        if name:startsWith(MarkEnum.UncompulsoryInvalidity) or name:startsWith(MarkEnum.InvalidSkills) then
          room:setPlayerMark(player, name, 0)
        end
      end
      local nums = { 1, 2, 3, 4, 5, 6, 7, 8 }
      table.removeOne(nums, 6)
      local rand = table.random(nums)
      if rand == 4 and player:isNude() then
        table.removeOne(nums, 4)
        rand = table.random(nums)
      end
      room:sendLog {
        type = "#sk__qianyuanLog",
        from = player.id,
        arg = "sk__qianyuan6",
        arg2 = "sk__qianyuan" .. rand,
        toast = true,
      }
      local count = 1
      if rand < 5 then
        count = player:getMark("sk__qianyuan_record" .. rand) == 0 and 1 or player:getMark("sk__qianyuan_record" .. rand)
      end
      DoQianyuan(player, rand, count, sk__qianyuan.name)
    else
      room:addTableMark(player, "@[sk__qianyuan]", "sk__qianyuan6")
      for _, name in ipairs(player:getMarkNames()) do
        if name:startsWith(MarkEnum.UncompulsoryInvalidity) or name:startsWith(MarkEnum.InvalidSkills) then
          room:setPlayerMark(player, name, 0)
        end
      end
    end
  end,
})
sk__qianyuan:addEffect(fk.BeforeChainStateChange, {
  name = "sk__qianyuan",
  anim_type = "defensive",
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(sk__qianyuan.name,true) then
      if player:hasSkill(sk__qianyuan.name) then
        if player.chained then return end
        return target == player and
            (not table.contains(player:getTableMark("@[sk__qianyuan]"), "sk__qianyuan7") or
              player:getMark("sk__qianyuan-turn") < #player.room.alive_players)
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    if table.contains(player:getTableMark("@[sk__qianyuan]"), "sk__qianyuan7") then
      return player.room:askForSkillInvoke(player, sk__qianyuan.name, nil,
        "#sk__qianyuan2-invoke:::" .. "sk__qianyuan7" .. ":" ..
        player:getMark("sk__qianyuan-turn"))
    else
      return player.room:askForSkillInvoke(player, sk__qianyuan.name, nil,
        "#sk__qianyuan1-invoke:::" .. "sk__qianyuan7")
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if table.contains(player:getTableMark("@[sk__qianyuan]"), "sk__qianyuan7") then
      room:addPlayerMark(player, "sk__qianyuan-turn", 1)
      local nums = { 1, 2, 3, 4, 5, 6, 7, 8 }
      table.removeOne(nums, 7)
      local rand = table.random(nums)
      if rand == 4 and player:isNude() then
        table.removeOne(nums, 4)
        rand = table.random(nums)
      end
      room:sendLog {
        type = "#sk__qianyuanLog",
        from = player.id,
        arg = "sk__qianyuan7",
        arg2 = "sk__qianyuan" .. rand,
        toast = true,
      }
      local count = 1
      if rand < 5 then
        count = player:getMark("sk__qianyuan_record" .. rand) == 0 and 1 or player:getMark("sk__qianyuan_record" .. rand)
      end
      DoQianyuan(player, rand, count, sk__qianyuan.name)
      data.prevented = true
    else
      room:addTableMark(player, "@[sk__qianyuan]", "sk__qianyuan7")
      data.prevented = true
    end
  end,
})
sk__qianyuan:addEffect(fk.BeforeTurnOver, {
  name = "sk__qianyuan",
  anim_type = "defensive",
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(sk__qianyuan.name,true) then
      if player:hasSkill(sk__qianyuan.name) then
        if target == player then
          if not player.faceup then return end
          return target == player and
              (not table.contains(player:getTableMark("@[sk__qianyuan]"), "sk__qianyuan8") or
                player:getMark("sk__qianyuan-turn") < #player.room.alive_players)
        end
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    if table.contains(player:getTableMark("@[sk__qianyuan]"), "sk__qianyuan8") then
      return player.room:askForSkillInvoke(player, sk__qianyuan.name, nil,
        "#sk__qianyuan2-invoke:::" .. "sk__qianyuan8" .. ":" ..
        player:getMark("sk__qianyuan-turn"))
    else
      return player.room:askForSkillInvoke(player, sk__qianyuan.name, nil,
        "#sk__qianyuan1-invoke:::" .. "sk__qianyuan8")
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if table.contains(player:getTableMark("@[sk__qianyuan]"), "sk__qianyuan8") then
      room:addPlayerMark(player, "sk__qianyuan-turn", 1)
      local nums = { 1, 2, 3, 4, 5, 6, 7, 8 }
      table.removeOne(nums, 8)
      local rand = table.random(nums)
      if rand == 4 and player:isNude() then
        table.removeOne(nums, 4)
        rand = table.random(nums)
      end
      room:sendLog {
        type = "#sk__qianyuanLog",
        from = player.id,
        arg = "sk__qianyuan" .. 8,
        arg2 = "sk__qianyuan" .. rand,
        toast = true,
      }
      local count = 1
      if rand < 5 then
        count = player:getMark("sk__qianyuan_record" .. rand) == 0 and 1 or player:getMark("sk__qianyuan_record" .. rand)
      end
      DoQianyuan(player, rand, count, sk__qianyuan.name)
      data.prevented = true
    else
      room:addTableMark(player, "@[sk__qianyuan]", "sk__qianyuan" .. 8)
      data.prevented = true
    end
  end,
})

return sk__qianyuan
